package com.example.a2032.Utils;

import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;


import com.example.a2032.BuildConfig;
import com.example.a2032.db.DataDbHelper;
import com.example.a2032.entity.EcgSaveInfo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

/**
 * SD卡管理操�?
 *
 * @author Jerry Lee
 */
public class SDUtil {
    public static final String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + BuildConfig.APPLICATION_ID;
    private static String TAG = SDUtil.class.getSimpleName();
    public static final String log = baseDir + "/Log";
    public static final String btCommandLog = log + "/btCommandLog";

    private static double MB = 1024;
    private static double FREE_SD_SPACE_NEEDED_TO_CACHE = 10;
    private static double IMAGE_EXPIRE_TIME = 10;


    /**
     * sd卡是否存�?
     *
     * @return
     */
    public static boolean existSDCard() {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            return true;
        } else
            return false;
    }

    public static String getDateString(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    public static String formatDate(Date date, String format) {
        String result = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            result = sdf.format(date);
        } catch (Exception e) {

        }

        return result;
    }


    public static void createFile(String fileName) {
        if (fileName == null)
            return;
        if (!existSDCard()) {
            return;
        }
        // 不存在则创建目录
        File dir = new File(btCommandLog);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String rFileName = btCommandLog + "/" + fileName + ".txt";
        File file = new File(rFileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存蓝牙命令log（测试用�?
     *
     * @param fileName
     * @param content
     */
    public static void saveBTLog(Context context, String fileName, String content) {
        String rootPath = context.getExternalFilesDir("").getAbsolutePath();
        if (content == null || fileName == null)
            return;
        if (!existSDCard()) {
            return;
        }
        // 不存在则创建目录
        File dir = new File(rootPath, "log");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, fileName + ".txt");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        OutputStreamWriter os = null;
        try {
            os = new OutputStreamWriter(new FileOutputStream(file, true));
            os.write("\r\n" + content);
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String saveBTLog(Context context, String fileName, byte[] value) {
        String filePath = "";
        String rootPath = context.getExternalFilesDir("").getAbsolutePath();
        if (value == null || fileName == null)
            return filePath;
        if (!existSDCard()) {
            return filePath;
        }
        // 不存在则创建目录
        File dir = new File(rootPath, "log");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, fileName);
        file = createOrRenameFile(file);

        try {
            OutputStream outputStream = new FileOutputStream(file, false);
            outputStream.write(value);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }

    public static String saveBTLog(Context context, String content) {
        String rootPath = context.getExternalCacheDir().getAbsolutePath();
        if (content == null)
            return null;
        if (!existSDCard()) {
            return null;
        }
        // 不存在则创建目录
        File dir = new File(rootPath, "log");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, "gps.txt");
        file = createOrRenameFile(file);
//		if (!file.exists()){
//			try {
//				file.createNewFile();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//		}
        OutputStreamWriter os = null;
        try {
            os = new OutputStreamWriter(new FileOutputStream(file, true));
            os.write("\r\n" + content);
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file.getAbsolutePath();
    }

    public static String[] getFileInfo(File from) {
        String fileName = from.getName();
        int index = fileName.lastIndexOf(".");
        String toPrefix = "";
        String toSuffix = "";
        if (index == -1) {
            toPrefix = fileName;
        } else {
            toPrefix = fileName.substring(0, index);
            toSuffix = fileName.substring(index, fileName.length());
        }
        return new String[]{toPrefix, toSuffix};
    }

    public static File createOrRenameFile(File from) {
        String[] fileInfo = getFileInfo(from);
        String toPrefix = fileInfo[0];
        String toSuffix = fileInfo[1];
        File file;
        file = createOrRenameFile(from, toPrefix, toSuffix);
        return file;

    }

    public static File createOrRenameFile(File from, String toPrefix, String toSuffix) {
        File directory = from.getParentFile();
        if (!directory.exists()) {
            if (directory.mkdir()) {
                Log.v(TAG, "Created directory " + directory.getAbsolutePath());
            }
        }
        File newFile = new File(directory, toPrefix + toSuffix);
        for (int i = 1; newFile.exists() && i < Integer.MAX_VALUE; i++) {
            newFile = new File(directory, toPrefix + '(' + i + ')' + toSuffix);
        }

        Log.w(TAG, "Couldn't rename file to " + newFile.getAbsolutePath());
        try {
            copy(from, newFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return newFile;
        // }
        // return newFile;
    }

    private static void copy(final File f1, final File f2) throws IOException {
        f2.createNewFile();

        final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
        final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");

        file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));

        file1.close();
        file2.close();
    }

    /**
     * 计算sdcard上的剩余空间
     *
     * @return
     */
    public static int getFreeSpace() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
                .getPath());
        double sdFreeMB = ((double) stat.getAvailableBlocks() * (double) stat
                .getBlockSize()) / MB;
        return (int) sdFreeMB;
    }

    public static void removeExpiredCache(String dirPath, String filename) {
        File file = new File(dirPath, filename);
        if (System.currentTimeMillis() - file.lastModified() > IMAGE_EXPIRE_TIME) {
            Log.i(TAG, "Clear some expiredcache files ");
            file.delete();
        }
    }

    public static void removeCache(String dirPath) {
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        if (FREE_SD_SPACE_NEEDED_TO_CACHE > getFreeSpace()) {
            int removeFactor = (int) ((0.4 * files.length) + 1);
            Arrays.sort(files, new FileLastModifSort());
            Log.i(TAG, "Clear some expiredcache files ");
            for (int i = 0; i < removeFactor; i++) {
                files[i].delete();
            }

        }

    }

    private static class FileLastModifSort implements Comparator<File> {
        @Override
        public int compare(File arg0, File arg1) {
            if (arg0.lastModified() > arg1.lastModified()) {
                return 1;
            } else if (arg0.lastModified() == arg1.lastModified()) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    public static String getRootPath(Context context){
        return context.getExternalFilesDir("").getAbsolutePath();
    }

    public static void saveEcgFile(Context context,final String time,final List<Integer> temp,int heartRate) {
        Log.i(TAG, "saveEcgFile: ");
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                String rootPath= getRootPath(context);
                EcgSaveInfo ecgSaveInfo=new EcgSaveInfo();
                ecgSaveInfo.setDate(time);
                ecgSaveInfo.setHeartRate(heartRate);
                ecgSaveInfo.setRootPath(rootPath);
                DataDbHelper.getInstance().getEcgInfoDao().insert(ecgSaveInfo);
                File fileOut = new File(rootPath,time+".ecg");
                try {
                    if (!fileOut.exists()) {
                        fileOut.createNewFile();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(fileOut);
                    OutputStreamWriter outStream = new OutputStreamWriter(fileOutputStream);
                    StringBuffer stringBuffer = new StringBuffer();
                    for (int i : temp) {
                        stringBuffer.append(i + ",");
                    }
                    outStream.write(stringBuffer.toString());
                    outStream.flush();
                    outStream.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                emitter.onComplete();
            }
        }).compose(SchedulersTransformer.io2MainObservable()).subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: "+e.getMessage());
            }

            @Override
            public void onComplete() {

            }
        });

    }
    public static void saveEcgFile(EcgSaveInfo ecgSaveInfo,final List<Integer> temp) {
        Log.i(TAG, "saveEcgFile: ");
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                String rootPath= ecgSaveInfo.getRootPath();
                String time=ecgSaveInfo.getDate();
                DataDbHelper.getInstance().getEcgInfoDao().insert(ecgSaveInfo);
                File fileOut = new File(rootPath,time+".ecg");
                try {
                    if (!fileOut.exists()) {
                        fileOut.createNewFile();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(fileOut);
                    OutputStreamWriter outStream = new OutputStreamWriter(fileOutputStream);
                    StringBuffer stringBuffer = new StringBuffer();
                    for (int i : temp) {
                        stringBuffer.append(i + ",");
                    }
                    outStream.write(stringBuffer.toString());
                    outStream.flush();
                    outStream.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                emitter.onComplete();
            }
        }).compose(SchedulersTransformer.io2MainObservable()).subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: "+e.getMessage());
            }

            @Override
            public void onComplete() {

            }
        });

    }


}